package org.groupg.practice.pool2;

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

// 定义资源对象
class Resource {
    private String name;

    public Resource(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

// 定义资源工厂
class ResourceFactory extends BasePooledObjectFactory<Resource> {
    private int counter = 0;

    @Override
    public Resource create() throws Exception {
        return new Resource("Resource-" + (++counter));
    }

    @Override
    public PooledObject<Resource> wrap(Resource resource) {
        return new DefaultPooledObject<>(resource);
    }
}

// 使用资源池
public class ResourcePoolExample {
    public static void main(String[] args) throws Exception {
        // 配置资源池
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxTotal(20); // 最大资源数
        config.setBlockWhenExhausted(true); // 资源耗尽时是否阻塞


        // 创建资源池
        GenericObjectPool<Resource> pool = new GenericObjectPool<>(new ResourceFactory());
        pool.setConfig(config);

        // 消费者线程
        class Consumer implements Runnable {
            private GenericObjectPool<Resource> pool;

            public Consumer(GenericObjectPool<Resource> pool) {
                this.pool = pool;
            }

            @Override
            public void run() {
                while (true) {
                    Resource resource = null;
                    try {
                        resource = pool.borrowObject();
                        System.out.println("Consumer " + Thread.currentThread().getName() + " got: " + resource.getName());
                        Thread.sleep(1000); // 模拟工作
                    } catch (Exception e) {
                        e.printStackTrace();
                    }finally {
                        if (resource != null) {
                            pool.returnObject(resource);
                        }
                    }
                }
            }
        }

        // 启动多个消费者线程
        for (int i = 0; i < 5; i++) {
            Thread consumerThread = new Thread(new Consumer(pool));
            consumerThread.start();
        }
    }
}